{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Principal Component Analysis"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Implementation of Principal Component Analysis for dimensionality reduction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> from mlxtend.feature_extraction import PrincipalComponentAnalysis"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Overview"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The sheer size of data in the modern age is not only a challenge for computer hardware but also a main bottleneck for the performance of many machine learning algorithms. The main goal of a PCA analysis is to identify patterns in data; PCA aims to detect the correlation between variables. If a strong correlation between variables exists, the attempt to reduce the dimensionality only makes sense. In a nutshell, this is what PCA is all about: Finding the directions of maximum variance in high-dimensional data and project it onto a smaller dimensional subspace while retaining most of the information."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### PCA and Dimensionality Reduction\n",
    "\n",
    "Often, the desired goal is to reduce the dimensions of a $d$-dimensional dataset by projecting it onto a $(k)$-dimensional subspace (where $k\\;<\\;d$) in order to increase the computational efficiency while retaining most of the information. An important question is \"what is the size of $k$ that represents the data 'well'?\"\n",
    "\n",
    "Later, we will compute eigenvectors (the principal components) of a dataset and collect them in a projection matrix. Each of those eigenvectors is associated with an eigenvalue which can be interpreted as the \"length\" or \"magnitude\" of the corresponding eigenvector. If some eigenvalues have a significantly larger magnitude than others that the reduction of the dataset via PCA onto a smaller dimensional subspace by dropping the \"less informative\" eigenpairs is reasonable."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### A Summary of the PCA Approach\n",
    "\n",
    "-  Standardize the data.\n",
    "-  Obtain the Eigenvectors and Eigenvalues from the covariance matrix or correlation matrix, or perform Singular Vector Decomposition.\n",
    "-  Sort eigenvalues in descending order and choose the $k$ eigenvectors that correspond to the $k$ largest eigenvalues where $k$ is the number of dimensions of the new feature subspace ($k \\le d$).\n",
    "-  Construct the projection matrix $\\mathbf{W}$ from the selected $k$ eigenvectors.\n",
    "-  Transform the original dataset $\\mathbf{X}$ via $\\mathbf{W}$ to obtain a $k$-dimensional feature subspace $\\mathbf{Y}$.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### References\n",
    "\n",
    "- Pearson, Karl. \"LIII. [On lines and planes of closest fit to systems of points in space.](http://www.tandfonline.com/doi/abs/10.1080/14786440109462720?journalCode=tphm17)\" The London, Edinburgh, and Dublin Philosophical Magazine and Journal of Science 2.11 (1901): 559-572."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 1 - PCA on Iris"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mlxtend.data import iris_data\n",
    "from mlxtend.preprocessing import standardize\n",
    "from mlxtend.feature_extraction import PrincipalComponentAnalysis\n",
    "\n",
    "X, y = iris_data()\n",
    "X = standardize(X)\n",
    "\n",
    "pca = PrincipalComponentAnalysis(n_components=2)\n",
    "pca.fit(X)\n",
    "X_pca = pca.transform(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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adMmREZGIiEhAdnZ2di1axc++ugj1NfXo6qqClOnTkVJSQm+/fZbvPTSSxg+fDiSk5Nxxx13oKKiAgMHDoTD4UBtbS3mz5+P2tpaNDc3Iy0tDffddx9SUlIwdOhQHDlyBDabDbm5uejWrRtWrlyJTz75BIIgYPr06Rg1ahRSU1Nx22234dtvv0VtbS1Wr16Nv/3tb6iqqkJ6enq7iv5WLMJLxsAARab397//HampqbDZbIiIiMArr7ziKcCZkpKCESNG4N133/Wcf+LECfzxj39Ely5dMHz4cFRVVWH9+vV45JFH8PTTT+P//u//8OWXX3o9x7lz57Bjxw60tLQgJSUFI0eOxLfffosVK1agX79+WLduHT744AOkpKS0a9/58+cxYMAAr2Ph4eHo1q0bvv/+e6xZswbvvfceYmJisHTpUhQUFCA6OhqXL1/G22+/jd27d+Odd97B9u3bceDAAWzevBnDhw/HuXPnkJaWhvj4eKSlpaG4uBiff/45/u3f/g3Tpk3DuXPn8PTTT6O4uBiXL1/G448/jldeeQUZGRnYt28fYmJicOrUKeTn5+PKlSuYMGEC7r//fgDA4MGDkZWVhZycHOzevRszZ87E2rVrRXt8VizCS8bAAEWm13qIr62bbrqp3bG4uDhPBfC+ffviypUrOH78uKcO2n333QcAWLNmjed3fvGLX3i2JBk4cCAqKirQr18/OBwOREdH49y5c0hKShJtww033ICzZ896HWtsbMQHH3yA+Ph43HLLLZ723H333di/fz/uuOMOz5BZt27dcPPNN8Nms6FHjx6efZH69++P+Ph4T/uOHz+OY8eOeYJkv379EBMT49lk8+c//7nn965cuYIzZ87gq6++8mwE2NTUhDNnznidGxsbi+rqatHrItIakyTI0mw2m6JjN998Mw4fPgwA+OSTT7BixQqvn5eVlaG5uRk//vgjjh49ivj4eCxcuBBLly7F8uXLcf3110Oqali/fv1w3XXXobi42HNs8+bNKC4uxoABA3Ds2DHU1dUBAA4ePOgJqmLtbO3cuXOoqqoCAHz22We45ZZbcPPNN+PTTz/1/PzixYvo2bOn6OP99Kc/xT333IMtW7Zg06ZNGDVqVLueXms2m81Smz2S8bEHRQRg1qxZyMzMxM6dOwG49o9yV7EHXL2L5557Dj/88ANmz56NXr16YezYsZgwYQK6d++OPn364Pz585KP/+abbyI7Oxtvv/02GhsbERcXhyVLlqBbt274zW9+g6lTpyIsLAxxcXH4z//8T+zevVu2zZGRkXj99ddRWVmJO+64A4888giGDBmCzMxMfPjhh6ivr0d2drbk3lCPPPIIDh48iMmTJ6Ourg7Dhw/32luqrbvuugszZ87E5s2bZYMnkRpYLJZIxoEDB5Cfn2+4jLv7778fH3/8caibQaQZDvEREZEhsQdFRESGxB4UEREZEgMUEREZEgMUEREZEgMUEREZEgMUEREZ0v8HDK3kBOGnOekAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "with plt.style.context('seaborn-whitegrid'):\n",
    "    plt.figure(figsize=(6, 4))\n",
    "    for lab, col in zip((0, 1, 2),\n",
    "                        ('blue', 'red', 'green')):\n",
    "        plt.scatter(X_pca[y==lab, 0],\n",
    "                    X_pca[y==lab, 1],\n",
    "                    label=lab,\n",
    "                    c=col)\n",
    "    plt.xlabel('Principal Component 1')\n",
    "    plt.ylabel('Principal Component 2')\n",
    "    plt.legend(loc='lower center')\n",
    "    plt.tight_layout()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 2 - Plotting the Variance Explained Ratio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mlxtend.data import iris_data\n",
    "from mlxtend.preprocessing import standardize\n",
    "\n",
    "X, y = iris_data()\n",
    "X = standardize(X)\n",
    "\n",
    "pca = PrincipalComponentAnalysis(n_components=None)\n",
    "pca.fit(X)\n",
    "X_pca = pca.transform(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2.91081808, 0.92122093, 0.14735328, 0.02060771])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pca.e_vals_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([72.77045209, 23.03052327,  3.68383196,  0.51519268])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pca.e_vals_normalized_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "tot = sum(pca.e_vals_)\n",
    "var_exp = [(i / tot)*100 for i in sorted(pca.e_vals_, reverse=True)]\n",
    "cum_var_exp = np.cumsum(pca.e_vals_normalized_*100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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Lv1rF1KLFy++qSfw8/PDz8+PNm3aANCtWzfmzZtHgwYNOHHiBL6+vpw4cQIfHx9z++zsbHP/7OxsfH198fPz48svvzTbrVYr999/f6nn9Pf3v6nX4EgZGRlV6nqcjfq3/Khvy1dV69/09PRS20t9MmLbtm289957zJ071/xzo2655Rb8/Pz48ccfAdi1axfNmjUjODiY1atXA7B69WoeeeQRALPdMAxzmRBfX1+CgoLYuXMnubm55ObmsnPnToKCgm64LhERcX52I6mJEyeSn59PWloasbGxbNq0idatW/+pk7z44os8//zzXLp0iSZNmjB9+nSKi4sZMWIECQkJNGrUyFwOpEuXLmzfvp2QkBA8PDyYNm0aAN7e3gwbNsx8AOOZZ57B29v7T9UlIiLOzS6k9uzZw7p164iIiODZZ59l0KBBDB8+/E+dxN/fn8TERLv2Dz/80K7NYrEwadKkUo8TExNjhpSIiFR9drf73N3dAfDw8MBqtVKjRg2ysrIqvDARERG7kVTXrl05e/YsTz75JNHR0VgsFo1eRETEIexC6plnngEgLCyMhx9+mIKCAurWrVvhhYmIiJghtWvXLgICAti8eXOpG4aGhlZYUSIiInBVSO3evZuAgAA+/fTTUjdUSImISEUzQyouLo7i4mIeeughevTo4ciaREREgN883efi4sKSJUscVYuIiEgJdo+gP/jgg7z//vscP36cM2fOmH9EREQqmt3TfatWrQIoMaL6s4seioiI3Ai7kNq6dasj6hAREbFjF1IABw8e5NChQxQWFpptVxYoFBERqSh2ITV37lzS0tI4fPgwXbp0ITU1lfbt2yukRESkwtk9OLFp0yY+/PBD/vKXvzB9+nTWrFlTYkQlIiJSUexCqlatWri4uODm5sa5c+do0KABR48edURtIiJSzdnd7mvVqhVnz54lNjaW6Ohoateuzb333uuI2kREpJqzC6nJkycD0L9/fx566CHOnTvH3XffXdF1iYiI2N/uGzp0KOvWrePChQvcdtttCigREXEYu5AaNGgQ6enphIeHExcXx8cff0xBQYEjahMRkWrO7nbf/fffz/3334/NZuOLL75gxYoVjBs3jq+//toR9YmISDVW6su8+fn5bN26lY0bN3LgwAGioqIqui4RERH7kBoxYgT79u0jKCiIAQMG0KlTJ1xc7O4KioiIlDu7kIqOjmbmzJm4uro6oh4RERGTXUh17tzZEXWIiIjY0X08ERFxWgopERFxWubtvgMHDvzuhi1btiz3YkRERK5mhtQrr7wCQGFhIfv37+euu+4C4Pvvv+fee+9l6dKljqlQRESqLTOkFi9eDMDIkSOZMmWKGVIHDx5kwYIFjqlORESqNbvPpH788UczoABatGhBRkZGhRYlIiICpTyC3qxZM8aPH0+vXr2wWCysXbuWZs2aOaI2ERGp5uxCavr06SxdupRFixYB0LFjR/r371/hhYmIiNiFVK1atejXrx+dO3emadOmjqhJREQEKOUzqZSUFCIjI3nqqacAyMjIYMiQIRVemIiIiF1IvfXWWyQkJODl5QWAv78/x44dq/DCRERE7ELK1dWVunXrOqIWERGREuw+k2revDnr1q3DZrORmZnJ4sWLadeunSNqExGRas5uJPXiiy9y6NAhatasyahRo/D09GT8+PGOqE1ERKo5u5GUh4cHI0eOZOTIkTf1RDabjT59+tCwYUPeffddjh49yqhRo8jNzeWee+7htddeo2bNmhQWFvLCCy9w4MABvL29ef3117ntttsAePfdd0lISMDFxYUJEybw0EMP3dQaRUTEudiF1E8//cSCBQs4duwYRUVFZvuV96Zu1KJFi2jWrBnnzp0DYMaMGTzxxBOEh4czceJEEhISGDBgACtXrsTLy4stW7aQnJzMjBkzeOONNzh06BDJyckkJydjtVoZNGgQmzZt0uKMIiJVmN3tvueeew5/f39GjBjBCy+8YP75M7Kzs9m2bRsxMTEAGIbBF198QVhYGABRUVGkpKQAsHXrVqKiogAICwtj165dGIZBSkoK4eHh1KxZkyZNmnD77bezb9++P1WXiIg4N7uRlJubGwMGDLipJ5k2bRpjxozh/PnzAJw+fRovLy/c3C6f3s/PD6vVCoDVaqVRo0ZmLXXr1uX06dNYrVbatGljHrNhw4bmPiIiUjXZhdTDDz/MkiVLCAkJoWbNmma7t7f3DZ3g008/xcfHh1atWpGWllbmdhaLBbg8yirte2W1l6YqTYibn59fpa7H2ah/y4/6tnxVl/61C6mkpCQA3n//fbPNYrGYt+Ou19dff83WrVtJTU2loKCAc+fO8fLLL3P27FmKiopwc3MjOzsbX19f4PKo6vjx4/j5+VFUVEReXh7e3t74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ffp05s2bx6OPPvq7o8PAwEC++uorHnzwQXPEU1a//p4buY7XXnuNRYsWERERQb9+/Th58iRBQUH07NmTfv36ERERQVxcXJn/4BCp7CxGWfeiKqn09HTat2/v6DJumoyMDPOziqooMTGR/fv3M3HiRIecv6r3ryOpb8tXVevfsn53ayQlIiJOq9o9OCHOJTo6mujoaEeXISJOSiMpERFxWgopERFxWgopERFxWgopERFxWtXywYnXtxy8qccbGdLiD7fp16/fdc2GnZaWxoIFCxgxYgQpKSkcPnyYwYMHl7n97Nmz6dixIw8++GCpx7kyR9/1Cg4OJiEhwZzS6WYbO3YsXbt2pVu3bmVuU9a13YiBAwfywgsv2L2L9WfdzBpF5P+pliHlCH9muYZHHnnEnIi0LM8999wNH9/ZOfu12Ww2p69RpLLS7b4Kci1LSqSmptKtWzf69+/Pli1bzH0TExOZMmUKeXl5BAcHm/P1Xbx4kS5dunDp0qUSy3aUdZw333yT999/3/y6Z8+eZGVlATBs2DCio6MJDw+3m+euNDt37uTRRx8lKirKnPEgLy+PsLAwfvzxRwBGjRrFihUrzOt/5ZVXiIqK4vHHHycnJ8fumHPnzqVPnz707NmTF1980eyXq68tODiYOXPmmMtdXJm14sKFC8THx9OnTx969+5tTiWUn5/PyJEjiYiIYMSIEeYSGFfbvn17iZBJS0tjyJAhAEyaNMnsl6uXxAgODmbu3Ln079+fjz/+uESNZV3HwIED+de//kVMTAxhYWF89dVXwP9b3iQiIoKIiAgWL14MlL3EiEh1opBygG+//ZZx48axYcMGsrKySE9Pp6CggBdffJF33nmH//znP/z66692+9WtW5e77rqLL7/8EoBPP/2UoKAgatSoYW5zLccpzbRp00hMTGTVqlUsXrzYnGewNDk5Obz99tssXLiQpKQkWrVqxcKFC6lbty4TJ04kPj6e5ORkcnNz6du3L3A5RO655x6SkpLo2LFjqetGPfbYY6xatYr169eTn5/Pp59+Wur569evT1JSEv369WPBggUAvPPOOzzwwAOsWrWKRYsW8a9//YsLFy6wdOlS3N3dWbduHUOGDDHnOrxaYGAg33zzDRcuXABgw4YNdO/eHYCRI0eSmJjI2rVr2b17N9999525X61atVi6dKk56ey1XIfNZiMhIYFx48aZfbB8+XKysrJISkpi3bp1REREcOnSJaZOncqcOXNITEykT58+vP7662X+TESqKt3uc4DSlpSoU6cOt912G//93/8NQK9evcxRyNV69OjBhg0beOCBB0hOTmbAgAElvv/jjz9e03F+a/Hixeao6/jx4xw5csScWPa3vvnmGw4dOkT//v2By5O2tm3bFrj8C//jjz9mypQprFmzxtzHxcXFnAcwMjKSZ5991u64aWlpzJ8/n/z8fM6cOUPz5s0JDg622y40NBSAVq1amTXv3LmTrVu3mqFVUFDA8ePH2b17NwMHDgQu9/Vdd91ldzw3NzceeughPv30U8LCwti+fbu5MOXGjRtZsWIFRUVF/Prrrxw+fJi7774boMS8htd6HVeW3biyHAfArl276NevH25ul/939Pb25uDBg6UuMSJS3SikHKC0JSXAfomK0gQHBzNr1izOnDnDgQMHeOCBB+y2Kes4Vy/tAZjLQaSlpfH555+zfPlyPDw8GDhw4B8uFREYGMisWbPsvldcXMzhw4epVasWZ86cMcP4j2osKCjgn//8J6tWraJRo0a8+eabZdZwZeR49bIlAHPmzCl10tZr6dcePXqwZMkS6tWrR+vWrfH09OTo0aMsWLCAhIQE6tWrx9ixY0vU5OHhYXecP7qO0pZcMQzDrsaylhgRqW50u89JNG3alKysLHN58OTk5FK3q1OnDq1bt+bll1+ma9euuLq6XvNxGjdubC5NceDAAfPzqLy8POrVq4eHhweHDx9m7969v1tr27Zt+frrrzly5Ahw+bOxn376Cbi8zlKzZs2YNWsW48aNM5fsKC4uNhdCXLdund1Ekld+kdevX5/z58+b216rK8uIXPn858p1duzY0VyG4+DBg3z//fel7n///ffz7bffsmLFCvNW3/nz5/Hw8KBu3bqcPHmS1NTUP6zjRq4jMDCQZcuWUVRUBFxeyqWsJUZEqptqOZK6lkfGK1qtWrWYMmUKgwcPpn79+rRv377MX0o9evTgueeeMz9gv9bjhIWFsWbNGiIjI2ndurV5S7Bz584sW7aMiIgI7rjjDvPWXVl8fHyYPn06o0aNorCwEIARI0YAsHLlSlauXImnpycdO3bk7bffJi4ujtq1a/PDDz8QHR2Np6cnb7zxRoljenl5ERsbS0REBI0bN77uR8SHDRvGtGnT6NWr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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "with plt.style.context('seaborn-whitegrid'):\n",
    "    fig, ax = plt.subplots(figsize=(6, 4))\n",
    "    plt.bar(range(4), var_exp, alpha=0.5, align='center',\n",
    "            label='individual explained variance')\n",
    "    plt.step(range(4), cum_var_exp, where='mid',\n",
    "             label='cumulative explained variance')\n",
    "    plt.ylabel('Explained variance ratio')\n",
    "    plt.xlabel('Principal components')\n",
    "    plt.xticks(range(4))\n",
    "    ax.set_xticklabels(np.arange(1, X.shape[1] + 1))\n",
    "    plt.legend(loc='best')\n",
    "    plt.tight_layout()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 3 - PCA via SVD"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "While the eigendecomposition of the covariance or correlation matrix may be more intuitiuve, most PCA implementations perform a Singular Vector Decomposition (SVD) to improve the computational efficiency. Another advantage of using SVD is that the results tend to be more numerically stable, since we can decompose the input matrix directly without the additional covariance-matrix step."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mlxtend.data import iris_data\n",
    "from mlxtend.preprocessing import standardize\n",
    "from mlxtend.feature_extraction import PrincipalComponentAnalysis\n",
    "\n",
    "X, y = iris_data()\n",
    "X = standardize(X)\n",
    "\n",
    "pca = PrincipalComponentAnalysis(n_components=2,\n",
    "                                 solver='svd')\n",
    "pca.fit(X)\n",
    "X_pca = pca.transform(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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adMmREZGIiEhAdnZ2di1axc++ugj1NfXo6qqClOnTkVJSQm+/fZbvPTSSxg+fDiSk5Nxxx13oKKiAgMHDoTD4UBtbS3mz5+P2tpaNDc3Iy0tDffddx9SUlIwdOhQHDlyBDabDbm5uejWrRtWrlyJTz75BIIgYPr06Rg1ahRSU1Nx22234dtvv0VtbS1Wr16Nv/3tb6iqqkJ6enq7iv5WLMJLxsAARab397//HampqbDZbIiIiMArr7ziKcCZkpKCESNG4N133/Wcf+LECfzxj39Ely5dMHz4cFRVVWH9+vV45JFH8PTTT+P//u//8OWXX3o9x7lz57Bjxw60tLQgJSUFI0eOxLfffosVK1agX79+WLduHT744AOkpKS0a9/58+cxYMAAr2Ph4eHo1q0bvv/+e6xZswbvvfceYmJisHTpUhQUFCA6OhqXL1/G22+/jd27d+Odd97B9u3bceDAAWzevBnDhw/HuXPnkJaWhvj4eKSlpaG4uBiff/45/u3f/g3Tpk3DuXPn8PTTT6O4uBiXL1/G448/jldeeQUZGRnYt28fYmJicOrUKeTn5+PKlSuYMGEC7r//fgDA4MGDkZWVhZycHOzevRszZ87E2rVrRXt8VizCS8bAAEWm13qIr62bbrqp3bG4uDhPBfC+ffviypUrOH78uKcO2n333QcAWLNmjed3fvGLX3i2JBk4cCAqKirQr18/OBwOREdH49y5c0hKShJtww033ICzZ896HWtsbMQHH3yA+Ph43HLLLZ723H333di/fz/uuOMOz5BZt27dcPPNN8Nms6FHjx6efZH69++P+Ph4T/uOHz+OY8eOeYJkv379EBMT49lk8+c//7nn965cuYIzZ87gq6++8mwE2NTUhDNnznidGxsbi+rqatHrItIakyTI0mw2m6JjN998Mw4fPgwA+OSTT7BixQqvn5eVlaG5uRk//vgjjh49ivj4eCxcuBBLly7F8uXLcf3110Oqali/fv1w3XXXobi42HNs8+bNKC4uxoABA3Ds2DHU1dUBAA4ePOgJqmLtbO3cuXOoqqoCAHz22We45ZZbcPPNN+PTTz/1/PzixYvo2bOn6OP99Kc/xT333IMtW7Zg06ZNGDVqVLueXms2m81Smz2S8bEHRQRg1qxZyMzMxM6dOwG49o9yV7EHXL2L5557Dj/88ANmz56NXr16YezYsZgwYQK6d++OPn364Pz585KP/+abbyI7Oxtvv/02GhsbERcXhyVLlqBbt274zW9+g6lTpyIsLAxxcXH4z//8T+zevVu2zZGRkXj99ddRWVmJO+64A4888giGDBmCzMxMfPjhh6ivr0d2drbk3lCPPPIIDh48iMmTJ6Ourg7Dhw/32luqrbvuugszZ87E5s2bZYMnkRpYLJZIxoEDB5Cfn2+4jLv7778fH3/8caibQaQZDvEREZEhsQdFRESGxB4UEREZEgMUEREZEgMUEREZEgMUEREZEgMUEREZ0v8HDK3kBOGnOekAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "with plt.style.context('seaborn-whitegrid'):\n",
    "    plt.figure(figsize=(6, 4))\n",
    "    for lab, col in zip((0, 1, 2),\n",
    "                        ('blue', 'red', 'green')):\n",
    "        plt.scatter(X_pca[y==lab, 0],\n",
    "                    X_pca[y==lab, 1],\n",
    "                    label=lab,\n",
    "                    c=col)\n",
    "    plt.xlabel('Principal Component 1')\n",
    "    plt.ylabel('Principal Component 2')\n",
    "    plt.legend(loc='lower center')\n",
    "    plt.tight_layout()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we compare this PCA projection to the previous plot in example 1, we notice that they are mirror images of each other. Note that this is not due to an error in any of those two implementations, but the reason for this difference is that, depending on the eigensolver, eigenvectors can have either negative or positive signs.\n",
    "\n",
    "For instance, if $v$ is an eigenvector of a matrix $\\Sigma$, we have\n",
    "\n",
    "$$\\Sigma v = \\lambda v,$$\n",
    "\n",
    "where $\\lambda$ is our eigenvalue\n",
    "\n",
    "then $-v$ is also an eigenvector that has the same eigenvalue, since\n",
    "\n",
    "$$\\Sigma(-v) = -\\Sigma v = -\\lambda v = \\lambda(-v).$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 4 - Factor Loadings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After evoking the `fit` method, the factor loadings are available via the `loadings_` attribute. In simple terms, the loadings are the unstandardized values of the eigenvectors. Or in other words, we can interpret the loadings as the covariances (or correlation in case we standardized the input features) between the input features and the principal components (or eigenvectors), which have been scaled to unit length.\n",
    "\n",
    "By having the loadings scaled, they become comparable by magnitude and we can assess how much variance in a component is attributed to the input features (as the components are  just a weighted linear combination of the input features)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mlxtend.data import iris_data\n",
    "from mlxtend.preprocessing import standardize\n",
    "from mlxtend.feature_extraction import PrincipalComponentAnalysis\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "X, y = iris_data()\n",
    "X = standardize(X)\n",
    "\n",
    "pca = PrincipalComponentAnalysis(n_components=2,\n",
    "                                 solver='eigen')\n",
    "pca.fit(X);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "xlabels = ['sepal length', 'sepal width', 'petal length', 'petal width']\n",
    "\n",
    "fig, ax = plt.subplots(1, 2, figsize=(8, 3))\n",
    "\n",
    "ax[0].bar(range(4), pca.loadings_[:, 0], align='center')\n",
    "ax[1].bar(range(4), pca.loadings_[:, 1], align='center')\n",
    "\n",
    "ax[0].set_ylabel('Factor loading onto PC1')\n",
    "ax[1].set_ylabel('Factor loading onto PC2')\n",
    "\n",
    "ax[0].set_xticks(range(4))\n",
    "ax[1].set_xticks(range(4))\n",
    "ax[0].set_xticklabels(xlabels, rotation=45)\n",
    "ax[1].set_xticklabels(xlabels, rotation=45)\n",
    "plt.ylim([-1, 1])\n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For instance, we may say that most of the variance in the first component is attributed to the petal features (although the loading of sepal length on PC1 is also not much less in magnitude). In contrast, the remaining variance captured by PC2 is mostly due to the sepal width. Note that we know from Example 2 that PC1 explains most of the variance, and based on the information from the loading plots, we may say that petal features combined with sepal length may explain most of the spread in the data."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 5 - Feature Extraction Pipeline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.pipeline import make_pipeline\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.model_selection import train_test_split\n",
    "from mlxtend.data import wine_data\n",
    "\n",
    "X, y = wine_data()\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=123, test_size=0.3, stratify=y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Transf. training accyracy: 96.77%\n",
      "Transf. test accyracy: 96.30%\n"
     ]
    }
   ],
   "source": [
    "pipe_pca = make_pipeline(StandardScaler(),\n",
    "                         PrincipalComponentAnalysis(n_components=3),\n",
    "                         KNeighborsClassifier(n_neighbors=5))\n",
    "\n",
    "pipe_pca.fit(X_train, y_train)\n",
    "\n",
    "\n",
    "print('Transf. training accyracy: %.2f%%' % (pipe_pca.score(X_train, y_train)*100))\n",
    "print('Transf. test accyracy: %.2f%%' % (pipe_pca.score(X_test, y_test)*100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example 6 - Whitening"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Certain algorithms require the data to be whitened. This means that the features have unit variance and the off-diagonals are all zero (i.e., the features are uncorrelated). PCA already ensures that the features are uncorrelated, hence, we only need to apply a simple scaling to whiten the transformed data.\n",
    "\n",
    "For instance, for a given transformed feature $X'_i$, we divide it by the square-root of the corresponding eigenvalue $\\lambda_i$:\n",
    "\n",
    "$$X'_{\\text{whitened}} = \\frac{X'_i}{\\sqrt{\\lambda_i}}.$$\n",
    "\n",
    "The whitening via the `PrincipalComponentAnalysis` can be achieved by setting `whitening=True` during initialization. Let's demonstrate that with an example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.model_selection import train_test_split\n",
    "from mlxtend.data import wine_data\n",
    "\n",
    "X, y = wine_data()\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=123, test_size=0.3, stratify=y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Regular PCA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAagAAAEYCAYAAAAJeGK1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzt3Xt0VOW5P/DvJBBCCJdyMUE9GRSx0h6wTRT0IFoh2HBJQQskMg6w5IiBKjHJiShgpJEQKGKgKGDSo3IJJ4GjpRisLpLSH5X2oERRK9RKCkEkQMCWEOIkIdm/P8YMuew9ey77Pt/PWizInmTmmTHuZ7/vft7ntQmCIICIiMhgwvQOgIiISAwTFBERGRITFBERGRITFBERGRITFBERGVI3vQNor7KyUu8QiIhIBwkJCV2OGSpBAeJBdnbs2DEMHz5cg2iCx1jVwVjVwVjVwVi9kxqccIqPiIgMiQmKiIgMiQmKiIgMiQmKiIgMiQmKiIgMiQmKiIgMiQmKiIgMiQmKiIgMiQmKrKO4GBgyBAgLc/9dXKx3REQUBMN1kiAKSHExMH8+0NDg/rq62v01ADgc+sVFRAHjCIqsYenSa8mpTUOD+zgRmRITFFnDqVP+HSciw2OCImuIi/PvOBEZHhMUWUNeHhAV1fFYVJT7OBGZEhMUWYPDARQWAnY7YLO5/y4sZIEEkYmxio+sw+FgQiKyEI6giIjIkJigiIjIkJigiIjIkJigiIjIkJigiIjIkDSt4mtpacGyZctw4sQJhIeHIz8/H3FcSElERCI0HUHt378fAFBSUoJFixYhPz9fy5cnIiIT0XQElZiYiJ/85CcAgDNnzmDgwIFavjwREZmITRAEQesXXbx4Mfbt24df//rXuOeeezzHKysrEdW5XY0Il8uFyMhINUNUDGNVB2NVB2NVB2P1rqGhAQkJCV0fEHRy/vx54Sc/+Ylw5coVz7HDhw/79LNHjx5VKyzFMVZ1MFZ1MFZ1MFbvpM79mt6D2r17N1599VUAQM+ePWGz2RAeHq5lCEREZBKaJqgHHngAR48ehcPhwLx587BkyRL06NFDyxCIjIXb1BNJ0rRIIioqCuvXr9fyJYmMi9vUE3nFhbpEeuE29UReMUER6UWPbeo5pUgmwgRFpJdgt6n3N9m0TSlWVwOCcG1KkUmKDIoJikgvwWxTH0iy4ZQimQwTFJFegtmmPpBko8eUIlEQuOU7kZ4C3aY+kGQTF+ceaYkdJzIgjqCIzCiQ+1fBTCkS6YAJisiMAkk2wUwpEumAU3xEZlJc7L7PdOoU0L8/0LMn8M037pFTXp58sgl0SpFIB0xQRGbRufPExYvuUdO2bUw6ZEmc4iPj4qLSa4qLgTlzWCZOIYUjKDIm9qm7pu2zaGkRf5xl4mRRHEGRMXFR6TVin0V7LBMni2KCImPiotJrvL1nlomThTFBkTEF26fOSqTec3g4y8TJ0pigyJiMvqhUywIOqc9iyxYmJ7I0JigyJn8XlWqZMLTuCs4FthSimKDIuBwO4ORJoLXV/be35KRlwtCjgMPXz6JNW8K22YBu3dx/h3qpPpkOExSZn9YJw+gFHO0TNnCtPJ37P5HJMEGROXSawutTVnbtMa0ThtELOLyVpYdqqT6ZEhMUGZ/IFN7gnJxrIwGtE4ZeBRy+3meTS8xGGekRyWCCInUoWbQgMiIIc7mujQS0Thh6FC2I3WdzOoGFC7t+r1xiNspIj0gGExQpT+miBbkpPD0Shr9FC8ESm7YTBGDz5q6fq1jCbmOkUn0iGUxQpDylixZ8mcLTOmGoSWz0KZWkBaHr59o+YQPuBb0Ay9PJdJigSHlKFy2IjAhaIyPVGwno2UVdavTZv7/0z4h9rm0JWxCAq1fdf5s9cVPIYYIi5SldtCAyhVeTm6vOyVbrNVWdSY0+Afd7F6PHPSVuhUIaYIIi5alRtNBpCq9uypSgQpSkdxd1qVFm2+aEnelxT0nvJE4hgwmKlGfm1jx6L8KVGg3ZbMCVKx2PDRigz+eqdxKnkKFZgmpubkZ2djZmzZqF6dOno6KiQquXJj2YtWhB70W4YqNPm809UuksOlqfz1XvJE4hQ7MEtWfPHvTr1w87duxAUVERXnjhBa1emtrjvQPv9O6iLjb6FEtOgH4JQe8kTiHDJghSv/3KunLlCgRBQHR0NP75z3+KjqIqKysRJbV+ox2Xy4XIyEi1QlWUkWLtU1aGwTk57kWu32mNjERNbi7qpkwxVKxy1Iy1T1kZBhUUoPvZs2iOjUVtRkZQ97zkYpV7vaHjxyOipqbLzzUNHowqhWcifPlc5X6PtMLfV3XoEWtDQwMSEhK6PiBo7PLly8Ijjzwi7Nmzp8tjhw8f9uk5jh49qnRYqjFUrHa7ILivxzv+sdsFQTBYrDIsE+v27YIQFdXxv0dUlPu4t+8BBGHAgI7fp3asneO22wXBZnP/rXAcvrDM74DB6BGr1Llf0yKJmpoazJ49G1OnTkVycrKWL00A7x0YkS8FB23TfgMGdPy+ixf1q57zZysUTilTgDRLUBcuXMCjjz6K7OxsTJ8+XauXpfZ478B4fL1ocDjcRRGdqVU9p0RiYTk6BUmzBLV582bU1dVh48aNcDqdcDqdcLWbwyYN6F0AQF35c9Gg1QhYqcTCcnQKUjetXmjZsmVYtmyZVi9HYtqmYZYudZ/U4uLcycksJeBWlJfnPvm3P5FLXTTExV3bhLDzcSV5Syz+/K5wSpmCxIW6ViM3NWPW9UlW5c+iZq1GwEolFk4pU5CYoKyEc/7m5OtFg1YdOpRKLJxSpiAxQVkJ5/ytT4sRsFKJxd+Eyoo/6kSze1CkAc75kxKUvFfpcPj2c22j/7YLrLbRf/t4KORwBGUlnPMnpRhhx2CO/kOeZII6cuQIHnroITz88MM4fPiw5/gvfvELTQKjAHDOn8yKo38SIZmgVq1ahbVr1yI3Nxd5eXl4//33AQB1dXWaBUd+MvM2FxTaOPonEZIJqnv37rjpppswbNgwFBYWYvXq1fjiiy9gk9rVk4zBqmXknW6g9ykr0zsiUhJH/yRCMkH16tULW7duRVNTEwYNGoQXX3wRTz31FL7++mst4yMSLZ8fnJPDKi8r4eifREgmqBdffBGXLl1CU1MTAOD73/8+NmzYgO9///uaBUcEQPQGepjLxRvoViM2+mfpeUiTTFDR0dF48sknEd2uQeUtt9yCjRs3ahIYkUcgN9B5YjM/LjwPeSwztyKrnJzb3ofUnppSN9B5YrMGlp6HPCYoqxE7OTud7nl9MyWr9u9DRGtkpPQNdJ7YjMnfCyeWnoc8yQTV0tKCpqYmPPHEE2hubkZTUxMaGxsxe/ZsLeMjf4mdnNtGIL6OJIwwAhN7H23sdtTk5krfQOeJzXgCGdWy9DzkSSaoN998E0lJSThw4ACSkpKQlJSEyZMn4/rrr9cyPvKX3ElYbiRhlOkxqfdhswEnT6JuyhTpn+WJzXgCGdWy9DzkSfbimzlzJmbOnIn//d//5Q64ZiK1Z1B73pKYUnsBBSuYvY/82WOJtCH1O+ntd5X7l4U82XtQY8aMQVFREV5++WXPHzIwsavOzryd5I0yPRbM1bPea2q4qLir8HD/jrex6sJz8olsgkpPT0d9fT0GDhzo+UMG1v7kDLhP0O3JneSNMj0WbJLR68TGRcXiWlr8O04EH7bb6NWrFzIyMrSIhZTSfouD4mL/pkiMND3m61YNRuJtUbHZ3ouS7Hbx6by2CykiEbIjqGHDhmHv3r34xz/+gRMnTuDEiRNaxEVK8Xckoff0mNkZZYrUaFjwQAGQHUEdO3YMx44d83xts9mwdetWVYMinZlx5GIUwRR3WBkLHigAsglq27ZtuHz5Mr7++mv827/9G3r16qVFXETmJDJF2hoZiTCOFHjhQ36TneJ777334HQ6kZ2djTfeeIO9+IjEtFXuOZ1Az57AgAGeKVKvi4rpGiMsECdDkU1Qr7/+Onbu3Il+/fph4cKFKC8v1yIuIvPoXLl38SLw7bfAtm3yi4rJzSgLxMlQZBNUWFgYIiIiYLPZYLPZ0LNnTy3iIjIPo/T+M/MIxCifIRmK7D2oO+64A5mZmTh37hxycnIwYsQILeIiMg8jVO61jUDaTvJtIxDAHNOLRvgMyXBkR1CZmZmYNm0aZsyYgfvvvx/PPPOMFnERmYcRFjebfQSi9Wdo5tFmCJFNUPX19Z5OEpcuXcLu3buDesFPPvkETqczqOcgMhQjrPEx+whEy8+Q97tMQ3aKb+HChbjuuuswePBgAO51UIEqKirCnj17eB+LrMUIa3zMvv5Ky8/QKA2RSZZsghIEAS+++KIiLxYXF4cNGzbg6aefVuT5iAxD7zU+RmpRFSitPkOzjzZDiE0QpPbTdluxYgWSk5MxfPhwz7GIiIiAX/D06dPIzMzEzp07uzxWWVmJKLlO3ABcLhciIyMDjkFLjFUdjLWrPmVlGFRQgO5nz6I5Nha1GRl+l7iHwuc6dPx4RNTUdDneNHgwqioqlAiti1D4XIPR0NCAhISELsdlR1AffPAB/vCHP3i+ttlsqFDpPyKADolQyrFjx3z6PiNgrOpgrCKGDweyswEAEQBu+O6PP0Lic12zRnS0GbFmjWrvPSQ+1yBUVlaKHpdNUHv27IEgCPjmm2/Qr18/hMvt30JE5G8XfS0Z4Z4h+US2iu/QoUNITEzEvHnzMGHCBBw8eFCLuIhIb4GWYpuhSo4bIZqC7Ahq3bp12LFjB2JiYnDu3Dk88cQTGDNmTMAveOONN4refyIiAwlm4S+r5EghsiOo8PBwxMTEAABiYmLQo0cP1YMiIp15SzJyIytWyZFCZEdQ0dHR2LZtG+688058+OGH6Nu3rxZxEZGepJJJ20jK28jK7GuyyDBkR1Br1qzBmTNnsG7dOtTU1GDlypVaxEVWwrYy5iOVTMLD5VsqGaGzBlmCbILq3bs34uPjER8fjzvvvJMjKPKPGW6YU1dSSaalRfz724+4HA6gsBCw2z17YqGwkPefyG+yCWrp0qV455130KNHD+zevZsjKPKP2ZuYhiqpJGO3i39/5xEXq+RIAbIJ6u9//zsKCgowZ84crF+/HkeOHNEiLrIK3jAPjp7To2JJRu3pO04HUzuyCSouLg5fffUVAODixYueprFEPjHCVhRmZcTpUTWn74z4fklXsgnqyJEjmDhxIh544AGMGzcOf/7zn3HPPffgnnvu0SI+MjveMA+cUadH1Zq+M+r7Jd3Ilpmr2XePQgDbygQu1KZHQ+39kizZBPWHP/wBb731FhobGz3HioqKVA2KjM+vVmt6b0VhVqG2nijU3i/Jkk1Qq1evRm5uLsvLySOYLjjkByvs8eSPUHu/JEs2QQ0bNgyjR4/WIhYyCbZa00ioTY+G2vslWbIJavz48UhJScHNN9/sOZafn69qUGRsvFWgoVCbHg2190teySaobdu24T//8z/Ru3dvLeIhE+CtAiLSgmyCGjhwICZNmqRFLGRAYsUQvFVARFqQTVCRkZGYN28efvCDH8BmswEAMjMzVQ+M9CdVDFFY6P7DWwVEpCbZBHX//fdrEQcZkLdiCLZXIyK1yXaSSE5ORkNDAz799FPU1dVh8uTJWsRFBsBiCLKa4s+KMWTdEIT9MgxD1g1B8Wdso2RksgkqJycHX331FcaMGYOvv/4ay5Yt0yIuMgC20SMrKf6sGPPfno/qS9UQIKD6UjXmvz2fScrAZBNUdXU1nnnmGSQmJmLJkiU4xcvnkME2emQlSyuWoqG545x1Q3MDllaw159RySaoxsZGfPvttwAAl8uFFqkNy8hyuO8cWcmpS+IX11LHSX+yRRKzZ8/G1KlTMWzYMBw/fhyLFi3SIi4yCK6bJKuI6xuH6ktdF/DF9eWctVHJjqB+9rOfYefOnUhLS0NJSQmLJEyC+74RdZQ3Pg9R3TvOWUd1j0LeeM5ZG5Vkgqqvr0dWVhbq6+vRr18/VFdXIzc3F/X19VrGRwHgvm9EXTlGOFCYXAh7XztssMHe147C5EI4RnCKwKgkE9Tzzz+PESNGoFevXgCApKQk/Pu//zuWL1+uVWwUIO77Rh4cSnfgGOHAyadOovX5Vpx86qRuyYnl7r6RTFA1NTWYO3eup3tEt27dMG/ePM/272Rcpli/xBOn+jiUNiSWu/tOMkGFhYk/1L17d9WCIWVIrVMKCzNIPuCJUxscSvtOwwsmlrv7TjJB2e12lJeXdzhWUVGBQYMGqR4UBUds/RIAtLQYJB9InDhPz1nKHKUkUwylDUDjCyaWu/tOMkEtXrwYJSUlePDBB/Hkk09i+vTpKC0txfPPPx/wi7W2tiInJwcpKSlwOp2oFtuzIdSocOXWef1SeHjX79H1QlriBHl9yykOpJTEViC+0XikKVXWznL3riTXQfXp0we/+c1vcObMGZw/fx6DBw9GTExMUC9WXl6OpqYmlJaW4siRI1i1ahU2bdoU1HOamop7p7dfvyQxW6vfhbTEhlKnEMedeZXEfVF8o/FIM298Hua/Pb/DNB/L3cXZBEEQtHqx/Px8jBw50rOWauzYsfjTn/7kebyyshJRYnNTnbhcLkRGRqoWp5K8xTp0/HhE1NR0Od40eDCqKioUi2H8+KGoqYnocnzw4CZUVFT5FKuS+pSVYXBODsJcLs+xK4jCYyjE/8ABm03A55//zetzWOV3QG19ysowqKAA3c+eRXNsLGozMlA3ZYrk94fi56rF/4edYy2rLkPBZwU423AWsVGxyBiRgSl26f8uWtLjd6ChoQEJCQldHxA0tGTJEuGPf/yj5+v77rtPaG5u9nx9+PBhn57n6NGjisemFq+x2myC4J717vjHZlM0hu3bBSEqquNLREW5j/scq9K2bxe+CrcLLbAJJ2AXHsZ2T2x2u/yPW+Z3wGBCMlZf/wcJQkh+rn6QOvfLdpJQUnR0NK5cueL5urW1Fd26yXZbsi6N7hH40lOvuNg90tKsys/hwP/bchK9o1pxE07if+AOxmZzz/7pXmlIoYNNJw1LMjukpKR41kC1EQQBNpsNJSUlAb1YfHw89u/fj0mTJuHIkSO49dZbA3oey9DwHoG3nnrXboW5pwEVvBUmGxPgvudUXe0+N7RNOGsVAxEANp00KMkE9dJLLyn+YhMmTMDBgweRmpoKQRCwcuVKxV/DVNqfoXXcO91bEZPaobSdF4YM6Vo3wYIJotAmmaBuuOEGAO79oN599100NzcDAM6fP4/c3NyAXiwsLCzgn7UsA1y5GWG5jNRrBbsSobhY9/xPRAGSvQe1ePFiAMBHH32E06dP41//+pfqQZH/gllOZYTlMlKvZbMFfi+KDSuIzE02QUVGRuLxxx9HTEwMVq1ahQsXLmgRF/kh2BOxEXbOzctzJ6POBCHw9ZLs9KMcKzQ3tcJ7CDWyCUoQBNTW1uLKlStoaGjApUuXtIjLMMzQ0zTYE3FbEdPgwU26FTE5HNcKJDoLdKrRCFOXVmCF5qZqvwcmP3XIJqgnnngC+/btw9SpUzF+/Hjce++9WsRlCGaZIlLiROxwABUVVWhtBU6e1Oc+jd0ufjzQqUYjTF1agRWam6r5HqyQwI1KNkHdeeedSEpKwsCBA/H73//ec08qFJhlisgqJ2KlpxqNMHVpBVZobqrUexAbKVkhgRuVbIIqLi5GamoqCgsLkZKSgt/97ndaxGUIZpkissqJWOn1kr4uUDb6FK7erNDcVIn3IDVSqr4kXmpqpgRuVLIJateuXXj77bfxyiuvYPfu3di6dasWcRmCWUYmVloI73C4pxiVmmr09nxmmcLVW974PER173gFZLbmpkq8B6mRUrhNZLsAmCuBG5VsghowYADCv9uvITIyEv369VM9KKMw08hE6RN7KDDLFK7eHCMcKEwuhL2vHTbYYO9rR2FyoW7bpQdCifcgNSJqEVpMn8CNSrYRniAImDZtGn784x/j6NGjuHr1KrKysgAAa9euVT1APRmk0QOpxCxTuEbgGOEwVUISE+x7iOsbJzqdZ+9rR974PCytWIpTl04hrm8c8sbnmf7zMgLZBJWWlub5d3JysqrBGJEBGj2QSiS2pTLcFC4Fpq2AQamk4W0fJyskcCOSnOLbv38/AOAf//gHTpw40eHPqFGjMGrUKM2CJFKDmaZwyT9qlH4HM01YVl3GdVIBkBxBtbU0YucIsipO4VqXt9LvYEY6gYyUij8rxtIPl6K51d3PtPpSNR793aOe5yNpkiOoBx98EIB7Wm/IkCF44okn4HK5MG3aNM2CI1Ibi0usyUhrt9J/n+5JTm2aWpqQ/vt0zWMxG5+axQ4aNAgAcN9992EpS5yIyOCMtHbr4rcX/TpO1/i0o+7o0aMBuLtKtLa2qhoQEVGwgln3xL56xiGboPr06YPS0lJ88cUX2LVrF3r16qVFXGQQ7LRAZhRoQYMaxRUDeg7w6zhdI5ugVq1ahePHj2PNmjWoqqriLrghJNhOC0xupCfHCAdOPnUSrc+34uRTJ30qSFCjr976ievRzdaxHq17WHesn7g+4OcMFbLroPr374+0tDQ0NjYCAFwul+pBWUVxMZCdPRRnz5qzQkyq08KcOe5/e3svbcmt7efbkpvczxHpSY3iCscIB858fQav/O0VLuT1k+wIavny5ZgxYwYyMzORkZGBzMxMLeIyvbYTdE1NhO593gIdyUh1VGhpkX8vSrQR4giMtKZWccUU+xS/R3Pkwwjq008/RXl5OcLCfKqnoO94O0FrOYIIZiQj1WkBkH8vwbYR4giM9OCtWwRpTzbr2O12z/ReqPPnij7QE7TSo4ZgRjJinRba8/Zegu0Ez0aupAcrNMa1EtkRVE1NDe6//37Yv9vu1GazoaSkRPXAjMbfK/pA+rypMWoIZiTT9ppz5rin9Trz9l7y8jq+F8C/NkJs5Epa69y7b9tD25iYdCY7glq7di3efPNNvPTSS3jppZcs38Fcir9X9IH0eVNj1BDsSMbhALZs8f+9BLtHlVn24iJr0HLbdjOvs9I6dskEtWvXLgBASUkJSktLO/wJRf5e0bedoAcPbvL5BK3GqEGJhqiBJptg2gixkStpSatt27VMhErTI3bJBBUbGwvAfQ/qpptu6vAnFAVyRe9wABUVVT6foNUYNSi1267WPeustEswGZ9Wvfu0SoRq0CN2yXtQY8eOBQC88847eO2111QLwCyCvaei52uYdU8rs8ZN5iO1GaHSvfuM1MTWX3rELnsPqnfv3qioqEBVVZVnP6hQpMUVPUcNRPoIpnefP4zUxNZfesQum6C++eYbvPHGG1i+fDlycnLw/PPPB/WC+/bt82wZbzZaTHNx+wci7WlVXm7mJrZaJfH2vJaZ19fXo7CwED179lTkxVasWIH3338fw4cPV+T5rK64mJvpEWlFi23b257f363o2woU2u4BtRUotH9OtQUaezAkR1Dbt2/Hz372M0ydOhV/+tOfFHmx+Ph4LF++XJHnsrpgG7W2PQdbBREZi5pNbNUeZQUSezBsgiAIYg+kpqZi69atqK+vx9NPP43f/OY3Pj/prl27sGXLlg7HVq5ciZEjR+LQoUMoKSlBQUFBl5+rrKxElLfWBd9xuVyIjIz0OR49BRrr+PFDUVMT0eV4375X8Ze/fCn782VlfZCTMxgu17VrkMjIVuTm1mDKlDpFY9UDY1UHY1VHsLH+cOcPIaDrqdoGGz6f+TkAoKy6DDmHc+BqudbQOzI8Erl35GKKfYpmsQaioaEBCQkJXY5LTvFFREQgIiIC/fv3R3Nzs9S3iZoxYwZmzJjhf5SAT9N/x44dM800YaCxnj0rfvzSpW746KPhslN9EycCnRvPu1xheOWVG5CdfYOiseqBsaqDsaoj2Fi9VRm2Pe/E9yZ2SE4A4Gpx4ZW/vYLspGzNYg1EZWWl6HGfOsBKDLJIRd7WPvnSWYKtgoisw5cCBTOXsEuRHEEdP34cWVlZEATB8+82odruSEt5ecAjj4g/5kuSCaQXIBEZky8FClqt5dKSZIJat26d59+pqamKveDo0aMxevRoxZ7PqhwOID0duHix62O+JBktFhYTkXbkqgytuFWIZIIaNWqUlnGEHF9KyNevBx59FGhqunYsIsK3JONwAAcPuhf6trQA4eHuruQsUyeyJj3KwNUWsrsQ6lmC7U8Jeefbf01N7pGVXLzFxe4u5G3bZLS0uL9mqTmRdWldBq62kExQCxcCTmdwa4yC4eu2GkuXAmIFlBcvarPlOpGZ6N1pQQ1WfE/+CLkEVVwMbN7cdWSi5cnb1wo7b8UQcvGyio9CycK9C+F8y2nKbSykmHlrDqWEXIJaurRrcmqj1cnb12015Ioh1Nxyncgsij8rxubDm7ssZDXLNhZSzLw1h1JCLkEFclJXmq+b8Yl9X3tyW65zwz8KBUsrlop2WQDMvQbIiuua/BVyCUrqpG6zaXfy9nVbjbbvGzCg63OoveU6kVl4O2GbeQ2QL9tbWP0eVcglKLGRhc0GpKW5/61VZZ+v22o4HMCFC8D27dpuuU5kFlInchtspl4DJNc9IhTuUYVcghIbWWzbBowZE3z3cF91LnFfuFA+MTLZkBUpMQIQO5HbYEPaHWmmLrOW26MqFO5Red0PyqrEthIfMkS6LFvJZNC2BqrttaqrgU2brj3elhjb4iSyKqX2ODLKAtXiz4oVj8Fb94hQuEcVkglKjFZl2WLrkzpTIzESGY23EYC/J3YtNhv0Ro8NBa3Ye6+zkJvik6JVWbavCY/rlcjqrDQC0GO6TY8t2LXGBPUdrcqyfU14XK9EVudLlZpZ6JFs5e5RWQET1He0KsuWW9sEqLdeiVvAk5FYaQSgV7K1Wu+9zpig2tGiUk4sES5YoH5i9KdBLZEWrDQCsFKyNRIWSehArIpQbd6ax7IYg/Sid3GDUoxSSWg1HEGZnK/TdmweS6QcsfVbVp9u0wNHUCYmtqZKag0Vt4AnUoZUSfnBUwfxzpfvcASlII6gTMyfPZ/YPJZIGVIl5ZsPb7Z02yE9MEGZmD/TdmweS6QMqdJxq233YQRMUDoLpvTb38XF7OdHFDx/SsfNuOjYSJigdBRs6Ten7YhKY8DkAAAQ4UlEQVSU42vjWqnmtGLMuOjYSJigdOTPPSQxnLYjUoY/W1eIrd9KuyON66BUwASlI6l7SNXVvk/5dZ62A9gtIhS0trYiJycHKSkpcDqdqBYr0SSf+dtLr3NJ+cbJGy2z6NhImKB05K3EO5ApP3aLMC6l20yVl5ejqakJpaWlyMrKwqpVq5QIM2Qp0UuP66CUxwSlI1/68vkz5RfslCGpo6ysj+IXDpWVlRg7diwA4Ec/+hH++te/KhRtaDJr41pu+U6q6XwPSUqwW3SwW4S+CgoGKX7hUF9fj+joaM/X4eHhuHr1auBPGOLM2EuPW74r6PLly0hLS8MjjzyClJQUfPzxx1q9tKG1v4dkt4t/T7BbdLBbhL7Onu0uejyYC4fo6GhcuXLF83Vrayu6dWNjmECZsXFtKGz5rlmCev3113HXXXdh+/btyM/PR25urlYvbRrBlo2z7NyYYmObRY8Hc+EQHx+PAwcOAACOHDmCW2+9NfAnIwDmu4dkpQ0fpWiWoObOnYvU1FQAQEtLC3r06KHVS5tGsGXjLDs3poyMWsUvHCZMmICIiAikpqYiPz8fzz77bHBBkumY9b6ZP2yCIAjy3+afXbt2YcuWLR2OrVy5EiNHjkRtbS0ee+wxLFmyBKNGjerwPZWVlYiSqxoA4HK5EBkZqWjMamGs6jBbrOXl16GgYBDOnu2O2NhmZGTUYsqUOr1D68Jsn2sox1pWXYacwzlwtbg8xyLDI5F7Ry6m2KcE/Lx6fK4NDQ1ISEjo+oCgob/97W/CpEmThD/+8Y+ijx8+fNin5zl69KiSYamKsaqDsaqDsfpn+6fbBXuBXbAttwn2Aruw/dPtot+nVqy+vr4/9Phcpc79mt1VPX78ONLT07Fu3TrcdtttWr0sEZGk4s+KA95kUGrbDQCa3b+yyoaPUjS7B7V27Vo0NTUhLy8PTqcTCxYs0OqlVaf0IkwiUl+wZdqhUEWnN81GUJs2bdLqpTTlz6aBRGQc3hKML6OS6kvi7aWkjpP/uFA3SOzeQGROwZZph9vC/TpO/mOCChK7NxCZU7Bl2i1Ci1/HyX9MUEEyYvcG3hMLHZ988gmcTqfeYZhSsO2N7H3FW79IHSf/MUEFyWjdG9jR3KBUuGooKirCsmXL0NjYGPRzhaJg2xuZsX+f2TBBBclo3Rt4T8x4+pSVqXLVEBcXhw0bNigUZWjyp71R587hAEzXv89smKAU0HnTQD2r93hPzHgGFRSoctXw05/+lA1iA+TvNhVSJekATNW/z2yYoCzGiPfEQl33s2fFH+BVgy4CWf+k5Zonq+/x5A8mKIsx2j0xAppjY8Uf4FWDZtqf9Of8do7fyUarzuGhsMeTP5igLMZo98QIqM3I4FWDjjqf9KXKwL0lG606h7M7RUdMUBZkpHtiBNRNmaLaVcONN96InTt3KhCldYmd9MV4SzZaVeyFwh5P/mCCItICrxp048vJXS7ZaLXjbijs8eQPlgARkaXF9Y0T7Y8XbgtHq9DqcxdzLTqH543P69AhHQjttVUhN4JilwWi0CI1PbflwS2GKw/XaqRmFiE1gmLncaLQ03ZyD3TfJ61ZfY8nf4RUgvLWZYEJisi6eNI3p5Ca4mOXBSIi8wipBMUuC2QVzc3NyM7OxqxZszB9+nRUVFToHZJhsTODeYVUgmKXBdKL0ifJPXv2oF+/ftixYweKiorwwgsvKBSptbAzg7mFVIJilwXSQ1l1meInyaSkJKSnp3u+Dg/nLq5i2JnB3CyVoHwpIed6SdJawWcFip8ke/XqhejoaNTX12PRokV46qmngg3TktiZwdwsk6C4UR8Z1dkG8W7mwZ4ka2pqMHv2bEydOhXJyclBPZdVsTODuVkmQXGjPjKq2CjxbubBnCQvXLiARx99FNnZ2Zg+fXrAz2N13PXW3CyToFhCTkaVMSJD8ZPk5s2bUVdXh40bN8LpdMLpdMLlcgUbquWwM4O5WWahblyce1pP7DiRnqbYp+D6G65XtJPBsmXLsGzZMgWjtC4u0jUvyySovLyObYwAlpCTcfAkSeQ/y0zxsYSciMhaLDOCAtzJiAmJiMgaLDOCIiIia9FsBNXQ0ICsrCxcunQJPXv2xJo1a9C/f3+tXp6IiExGsxHUzp078cMf/hA7duzA5MmTsXHjRq1emoiITMgmCIKg1Yu1tLQgPDwcL7/8Mrp164a0tLQOj1dWViKqczdXES6XC5GRkWqFqSjGqg7Gqg7Gqg7G6l1DQwMSEhK6HFdlim/Xrl3YsmVLh2MrV67EyJEjMXv2bPz973/H66+/Lvqzw4cPl33+Y8eO+fR9RsBY1cFY1cFY1cFYvausrBQ9rkqCmjFjBmbMmCH62NatW1FVVYXHH38c5eXlarw8ERFZgGZTfK+++ipiYmIwbdo01NTUYO7cuXjvvfc6fI9UFiUiImsTm+LTLEFduHABixcvRlNTE1paWpCVlSUaEBEREaBxkQQREZGvuFCXiIgMiQmKiIgMybQJqqqqCgkJCWhsbNQ7FK8aGhqwYMECzJo1C/PmzcM333yjd0iSLl++jLS0NDzyyCNISUnBxx9/rHdIsvbt24esrCy9wxDV2tqKnJwcpKSkwOl0olpsPxgD+eSTT+B0OvUOQ1ZzczOys7Mxa9YsTJ8+HRUVFXqHJKmlpQXPPvssUlNT4XA4cMoEG9RdvHgR9913H6qqqvQOxZwJqr6+HqtXr0ZERITeocgyUweN119/HXfddRe2b9+O/Px85Obm6h2SVytWrMDatWvR2tqqdyiiysvL0dTUhNLSUmRlZWHVqlV6hySpqKgIy5YtM/wFHwDs2bMH/fr1w44dO1BUVIQXXnhB75Ak7d+/HwBQUlKCRYsWIT8/X+eIvGtubkZOTo5hFhWbLkEJgoDnnnsOmZmZ6Nmzp97hyJo7dy4WLFgAADhz5gwGDhyoc0TS5s6di9TUVADuK78ePXroHJF38fHxWL58ud5hSKqsrMTYsWMBAD/60Y/w17/+VeeIpMXFxWHDhg16h+GTpKQkpKene74ODw/XMRrvEhMTPQnU6P//A8Dq1auRmpqK6667Tu9QABh8uw2xjhTXX389Jk2ahNtuu02nqKQF00FDa95ira2tRXZ2NpYsWaJTdB1JxTpp0iQcOnRIp6jk1dfXIzo62vN1eHg4rl69im7djPe/3U9/+lOcPn1a7zB80qtXLwDuz3fRokV46qmndI7Iu27dumHx4sXYt28ffv3rX+sdjqS33noL/fv3x9ixY1FYWKh3OABMWGY+YcIExMbGAgCOHDmCkSNHori4WOeofGOGDhpffPEFMjMz8fTTT+O+++7TOxxZhw4dQklJCQoKCvQOpYv8/HzcfvvtmDRpEgDg3nvvxYEDB3SOStrp06eRmZmJnTt36h2KrJqaGvziF7/w3Icyg9raWsycORN79+71qeeo1hwOB2w2G2w2G44dO4YhQ4Zg06ZNGDRokG4xGe9STsa+ffs8/x43bhxee+01HaOR176DRlRUlKGnI44fP4709HSsW7fOkCNUs4mPj8f+/fsxadIkHDlyBLfeeqveIVnChQsX8OijjyInJwd333233uF4tXv3bpw7dw6PP/44evbsCZvNZthzQPsLfafTieXLl+uanAATJiiz+fnPf47FixfjzTffREtLC1auXKl3SJLWrl2LpqYm5OXlAQCio6OxadMmnaMyrwkTJuDgwYNITU2FIAiG/m9vJps3b0ZdXR02btzoKToqKioyzI399h544AE8++yzcDgcuHr1KpYsWWL4e7tGYropPiIiCg2mq+IjIqLQwARFRESGxARFRESGxARFRESGxARFRESGxARFpnbo0CHcfffdcDqdcDqdmDlzJrZt29bl+w4cOIDS0lK/nvutt97yuxHp6dOnMXPmzC7HL126hCVLlsDhcCA1NRUZGRm4fPmyX8+tt9LSUjQ3N4s+ZuSmvWReXAdFpnfXXXd5Okk0NTUhKSkJU6dORZ8+fTzfc++99/r9vA899JBiMWZmZiI1NRUTJkwAALzxxhvIyckxZAcMKa+++iqmTZvW5fiKFSvw/vvvY/jw4TpERVbGBEWWUl9fj7CwMISHh8PpdOJ73/se6urqMHnyZFRXVyM1NRVZWVmIjY3FV199hREjRuCXv/wlLl68iGeeeQaXL1+GIAhYvXo13n77bQwcOBA333wzNm/ejLCwMNTW1iIlJQUOhwMffPABXn75ZQCAy+XC6tWr0b179y4xff3117hw4YInOQHulfo///nPAbi7c2/ZsgUREREYMmQIcnNz8fbbb2P//v1wuVyora3F7NmzUVFRgS+//BJPP/00EhMTMX78eNx+++04deoUhg0bhry8PNTX1yM7Oxv19fVoaWlBeno67r77biQnJ2PUqFH44osvYLPZsHHjRvTu3Rtr167Fhx9+CEEQMHfuXEycOBFOpxO33XYbvvzyS9TX12P9+vX485//jNraWmRkZHTpyB8fH4/ExES/R6hEcpigyPT+7//+D06nEzabDd27d8dzzz3naSianJyMCRMm4K233vJ8/8mTJ/Hf//3f6NmzJxITE1FbW4tXX30V48aNw8MPP4y//OUv+PTTTzu8xrlz57B79260trYiOTkZSUlJ+PLLL7FmzRrExMRg8+bNePfdd5GcnNwlvvPnz+PGG2/scCw8PBy9e/fGP//5T2zYsAG//e1vER0djZUrV6K0tBRRUVG4cuUKXnvtNezduxdvvPEGdu7ciUOHDmHr1q1ITEzEuXPnkJ6eDrvdjvT0dJSXl+Pjjz/Gf/zHf2DOnDk4d+4cHn74YZSXl+PKlSuYPHkynnvuOWRlZeHAgQOIjo7G6dOnUVJSgsbGRsycORNjxowBAIwcORJLly5FQUEB9u7di/nz52PTpk2iIz6jN+0l82KCItNrP8XX2U033dTlWFxcnKfL+KBBg9DY2IgTJ054mo629Xdrv/3Ej3/8Y8/+Y8OGDcOpU6cQExODvLw8REVF4dy5c4iPjxeN4frrr8fZs2c7HGtubsa7774Lu92OW265xRPPnXfeiffffx+33367Z8qsd+/eGDp0KGw2G/r27evZs2nw4MGw2+2e+E6cOIGqqipPkoyJiUF0dLRnk8wf/OAHnp9rbGzEmTNn8Pnnn3s2Kbx69SrOnDnT4XtjY2Nx4cIF0fdFpDYWSZCl2Ww2n44NHToUn332GQDgww8/xJo1azo8fuzYMbS0tODbb7/F8ePHYbfbsWzZMqxcuRKrVq3CddddB6muYTExMfje977XoYv91q1bUV5ejhtvvBFVVVVoaGgAAHzwwQeepCoWZ3vnzp1DbW0tAOCjjz7CLbfcgqFDh+Lw4cOex+vq6tCvXz/R57v55psxevRobNu2DVu2bMHEiRO7jPTas9lsht0ckqyJIygiAGlpaViyZAn27NkDwL3f1O7duz2PX716FY899hj+9a9/YcGCBejfvz+mTp2KmTNnok+fPhg4cCDOnz8v+fy/+tWvkJubi9deew3Nzc2Ii4vDihUr0Lt3bzz55JOYPXs2wsLCEBcXh//6r//C3r17ZWOOiIjACy+8gJqaGtx+++0YN24cEhISsGTJErz33ntwuVzIzc2V3H9q3Lhx+OCDDzBr1iw0NDQgMTGxw/5Vnd1xxx2YP38+tm7dKps8iZTAZrFEMoy659SYMWNw8OBBvcMgUg2n+IiIyJA4giIiIkPiCIqIiAyJCYqIiAyJCYqIiAyJCYqIiAyJCYqIiAzp/wMwKxiEa+9LUgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sc = StandardScaler()\n",
    "\n",
    "pca1 = PrincipalComponentAnalysis(n_components=2)\n",
    "\n",
    "X_train_scaled = sc.fit_transform(X_train)\n",
    "X_train_transf = pca1.fit(X_train_scaled).transform(X_train_scaled)\n",
    "\n",
    "\n",
    "with plt.style.context('seaborn-whitegrid'):\n",
    "    plt.figure(figsize=(6, 4))\n",
    "    for lab, col in zip((0, 1, 2),\n",
    "                        ('blue', 'red', 'green')):\n",
    "        plt.scatter(X_train_transf[y_train==lab, 0],\n",
    "                    X_train_transf[y_train==lab, 1],\n",
    "                    label=lab,\n",
    "                    c=col)\n",
    "    plt.xlabel('Principal Component 1')\n",
    "    plt.ylabel('Principal Component 2')\n",
    "    plt.legend(loc='lower center')\n",
    "    plt.tight_layout()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Covariance matrix:\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[4.9, 0. ],\n",
       "       [0. , 2.5]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.set_printoptions(precision=1, suppress=True)\n",
    "\n",
    "print('Covariance matrix:\\n')\n",
    "np.cov(X_train_transf.T)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we can see, the features are uncorrelated after transformation but don't have unit variance."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### PCA with Whitening"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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vvrqK4u6ZCZXrlzBvffea7HN19cXwcHB+Ne//oUNGzbg888/R1BQEPLz81FaWoqAgAC0tLRgy5Yt2L9/Pz7++GPs3LkThw8fxrZt2zBu3DhcvnwZCxcuRGRkJBYuXIjy8nL885//xL/9279hxowZuHz5MlJSUlBeXo6WlhZMnDgRf/nLX7BkyRIcPHgQQUFBuHDhAnbs2IG2tjYkJibiqaeeAmAszZSVlYWCggLs378fL730Et5//32rLT5bxYgJcQQlKOJxOnbxdXbfffd12aZSqcyVu3v37o22tjacO3fOXFfsySefBACLpRBMS2UAwIABA1BXV4fw8HDk5eUhICAAly9fRkxMjNUY+vbti4aGBotter0eX331FSIjI/HAAw+Y43nsscdw6NAhPPzww+Yus+DgYERFRUGhUKBHjx5oa2sDAPTp0weRkZHm+M6dO4fq6mpzkgwPD0dQUJB5oceHHnrI/Ly2tjZcunQJp06dMi+Yd+vWLVy6dMnisREREbh69arV90UI32iQBPEqCoXCrm1RUVE4efIkAODnn3/GmjVrLPZXVVWhvb0dN2/exG+//YbIyEisWLEC+fn5WL16Ne655x6wVRELDw/H3XffjfLycvO2bdu2oby8HPfeey+qq6vR2toKAPjpp5/MSdVanB1dvnwZjY2NAICjR4/igQceQFRUlHn9ncuXL6O5uRk9e/a0+nr3338/Ro4cieLiYhQVFWHChAldWnodKRQKGAwGmzER4gpqQRFixdy5c7F8+XLs3bsXgHEdrT179pj337p1C3PmzMG1a9fwyiuvIDQ0FJMmTUJiYiJCQkLQq1cvXLlyhfX13377beTm5mLLli3Q6/VQqVRYuXIlgoODsWDBAqSnp8PHxwcqlQr/+Z//if3793PGrFQq8eabb6K+vh4PP/wwxo4dixEjRmD58uX4+uuvodVqkZuba142o7OxY8fip59+QmpqKlpbWzFu3DiLNaE6e/TRR/HSSy9h27ZtnMmTEGdQsVhCHHT48GHs2LFDciPunnrqKXz//fdih0EIb6iLjxBCiCRRC4oQQogkUQuKEEKIJFGCIoQQIkmUoAghhEgSJShCCCGSRAmKEEKIJP0/jkStqnsWB94AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sc = StandardScaler()\n",
    "\n",
    "pca1 = PrincipalComponentAnalysis(n_components=2, whitening=True)\n",
    "\n",
    "X_train_scaled = sc.fit_transform(X_train)\n",
    "X_train_transf = pca1.fit(X_train_scaled).transform(X_train_scaled)\n",
    "\n",
    "\n",
    "with plt.style.context('seaborn-whitegrid'):\n",
    "    plt.figure(figsize=(6, 4))\n",
    "    for lab, col in zip((0, 1, 2),\n",
    "                        ('blue', 'red', 'green')):\n",
    "        plt.scatter(X_train_transf[y_train==lab, 0],\n",
    "                    X_train_transf[y_train==lab, 1],\n",
    "                    label=lab,\n",
    "                    c=col)\n",
    "    plt.xlabel('Principal Component 1')\n",
    "    plt.ylabel('Principal Component 2')\n",
    "    plt.legend(loc='lower center')\n",
    "    plt.tight_layout()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Covariance matrix:\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[1., 0.],\n",
       "       [0., 1.]])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.set_printoptions(precision=1, suppress=True)\n",
    "\n",
    "print('Covariance matrix:\\n')\n",
    "np.cov(X_train_transf.T)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we can see above, the whitening achieves that all features now have unit variance. I.e., the covariance matrix of the transformed features becomes the identity matrix."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "## PrincipalComponentAnalysis\n",
      "\n",
      "*PrincipalComponentAnalysis(n_components=None, solver='svd', whitening=False)*\n",
      "\n",
      "Principal Component Analysis Class\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `n_components` : int (default: None)\n",
      "\n",
      "    The number of principal components for transformation.\n",
      "    Keeps the original dimensions of the dataset if `None`.\n",
      "\n",
      "- `solver` : str (default: 'svd')\n",
      "\n",
      "    Method for performing the matrix decomposition.\n",
      "    {'eigen', 'svd'}\n",
      "\n",
      "- `whitening` : bool (default: False)\n",
      "\n",
      "    Performs whitening such that the covariance matrix of\n",
      "    the transformed data will be the identity matrix.\n",
      "\n",
      "**Attributes**\n",
      "\n",
      "- `w_` : array-like, shape=[n_features, n_components]\n",
      "\n",
      "    Projection matrix\n",
      "\n",
      "- `e_vals_` : array-like, shape=[n_features]\n",
      "\n",
      "    Eigenvalues in sorted order.\n",
      "\n",
      "- `e_vecs_` : array-like, shape=[n_features]\n",
      "\n",
      "    Eigenvectors in sorted order.\n",
      "\n",
      "- `e_vals_normalized_` :  array-like, shape=[n_features]\n",
      "\n",
      "    Normalized eigen values such that they sum up to 1.\n",
      "    This is equal to what's often referred to as\n",
      "    \"explained variance ratios.\"\n",
      "\n",
      "- `loadings_` : array_like, shape=[n_features, n_features]\n",
      "\n",
      "    The factor loadings of the original variables onto\n",
      "    the principal components. The columns are the principal\n",
      "    components, and the rows are the features loadings.\n",
      "    For instance, the first column contains the loadings onto\n",
      "    the first principal component. Note that the signs may\n",
      "    be flipped depending on whether you use the 'eigen' or\n",
      "    'svd' solver; this does not affect the interpretation\n",
      "    of the loadings though.\n",
      "\n",
      "**Examples**\n",
      "\n",
      "For usage examples, please see\n",
      "    [http://rasbt.github.io/mlxtend/user_guide/feature_extraction/PrincipalComponentAnalysis/](http://rasbt.github.io/mlxtend/user_guide/feature_extraction/PrincipalComponentAnalysis/)\n",
      "\n",
      "### Methods\n",
      "\n",
      "<hr>\n",
      "\n",
      "*fit(X, y=None)*\n",
      "\n",
      "Learn model from training data.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : {array-like, sparse matrix}, shape = [n_samples, n_features]\n",
      "\n",
      "    Training vectors, where n_samples is the number of samples and\n",
      "    n_features is the number of features.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `self` : object\n",
      "\n",
      "\n",
      "<hr>\n",
      "\n",
      "*get_params(deep=True)*\n",
      "\n",
      "Get parameters for this estimator.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `deep` : boolean, optional\n",
      "\n",
      "    If True, will return the parameters for this estimator and\n",
      "    contained subobjects that are estimators.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `params` : mapping of string to any\n",
      "\n",
      "    Parameter names mapped to their values.'\n",
      "\n",
      "    adapted from\n",
      "    https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/base.py\n",
      "    # Author: Gael Varoquaux <gael.varoquaux@normalesup.org>\n",
      "    # License: BSD 3 clause\n",
      "\n",
      "<hr>\n",
      "\n",
      "*set_params(**params)*\n",
      "\n",
      "Set the parameters of this estimator.\n",
      "The method works on simple estimators as well as on nested objects\n",
      "(such as pipelines). The latter have parameters of the form\n",
      "``<component>__<parameter>`` so that it's possible to update each\n",
      "component of a nested object.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "self\n",
      "\n",
      "adapted from\n",
      "https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/base.py\n",
      "# Author: Gael Varoquaux <gael.varoquaux@normalesup.org>\n",
      "# License: BSD 3 clause\n",
      "\n",
      "<hr>\n",
      "\n",
      "*transform(X)*\n",
      "\n",
      "Apply the linear transformation on X.\n",
      "\n",
      "**Parameters**\n",
      "\n",
      "- `X` : {array-like, sparse matrix}, shape = [n_samples, n_features]\n",
      "\n",
      "    Training vectors, where n_samples is the number of samples and\n",
      "    n_features is the number of features.\n",
      "\n",
      "**Returns**\n",
      "\n",
      "- `X_projected` : np.ndarray, shape = [n_samples, n_components]\n",
      "\n",
      "    Projected training vectors.\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "with open('../../api_modules/mlxtend.feature_extraction/PrincipalComponentAnalysis.md', 'r') as f:\n",
    "    s = f.read()\n",
    "print(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  },
  "toc": {
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
